package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strconv"
)

type Data struct {
	hash string "哈希值"
	//magnet     string "磁力链接"
	title      string "标题"
	file       string "文件列表"
	fileNumber int    "文件数量"
	time       int64  "种子创建时间"
	fileSize   int64  "文件体积"
	indexTime  int64  "收录时间"
}

// 文件列表
var torrentList chan string = make(chan string)

// 检测结果
var result chan Data = make(chan Data)

// 线程数
var thread chan int = make(chan int)
var workThread int

// 关闭程序
var clo chan bool = make(chan bool)

// 根据线程参数启动解析器
func runParser() {
	t, ok := <-thread
	workThread = t
	if ok {
		for i := 1; i <= workThread; i++ {
			go Parser(strconv.Itoa(i))
		}
	}
	// 等待线程终止
	for <-thread == -1 {
		workThread--
		if workThread == 0 {
			// 全部线程已终止，关闭结果写入，退出程序
			close(result)
			break
		}
	}
}

// 读取种子列表文件
func getTorrentList(TorrentPath string, TorrentList string) {
	if TorrentPath == "-" {
		TorrentPath = ""
	} else {
		TorrentPath = TorrentPath + "/"
	}
	fin, err := os.Open(TorrentList)
	defer fin.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	buff := bufio.NewReader(fin)
	for {
		// 逐行读取，没有多余字符
		line, _, err := buff.ReadLine()
		if len(line) > 0 {
			fullpath := TorrentPath + string(line)
			torrentList <- fullpath
		}
		if err != nil {
			break
		}
	}
	close(torrentList)
}

// 处理参数
func processFlag(arg []string) {
	// 线程数
	t, err := strconv.Atoi(arg[3])
	if err != nil {
		// 线程数设置错误
		fmt.Println("线程数设置错误")
		return
	}
	// 限制最大线程数 500
	if t < 1 {
		t = 1
	} else if t > 500 {
		t = 500
	}
	fmt.Println("线程数量：", t)
	// 传递启动进程数
	thread <- t

	// 处理文件列表
	TorrentPath := arg[0]
	TorrentList := arg[1]
	// 传递URL列表
	getTorrentList(TorrentPath, TorrentList)

}

func main() {

	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.Parse()

	if flag.NArg() < 4 {
		// 参数不合法
		println("Usage:", os.Args[0], "TorrentPath TorrentList.lst OutType(file,db or both) ThreadNumber")
		fmt.Println("Author: Frank Kung <i@kongfanjian.com>")
		return
	}

	// 启动数据写入线程
	switch os.Args[3] {
	case "db":
		fmt.Println("写入数据库")
		go writeToDb()
	case "file":
		fmt.Println("写入文件")
		go writeToFile()
	case "both":
		fmt.Println("同时写入数据库和文件")
	default:
		fmt.Println("请选择正确的数据保存位置:db,file,both")
		return
	}

	// 获取参数
	args := make([]string, 0, 3)
	for i := 0; i < flag.NArg(); i++ {
		args = append(args, flag.Arg(i))
	}

	// 启动检测线程
	go runParser()

	// 参数处理
	processFlag(args)

	// 等待退出指令
	<-clo
	fmt.Println("Exit")
}
